﻿using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using vitecore.Module;
using vite_ef.Repositories.EntityFrameworkCore;
using vite_ef;
using vite_entity;
using vite_entity.Entities;

namespace vite_services
{
    [InjectOn(ServiceLifetime.Scoped, Scheme = InjectScheme.None, Own = true)]
    /*
     注册方式 
    1: [InjectOn]
      public class MyService : IAService, IBService
    ==等同于
    services.AddTransient<IAService, MyService>();
    services.AddTransient<IBService, MyService>();
    2:  [InjectOn(
        lifetime: ServiceLifetime.Transient,
        Scheme = InjectScheme.Some,
        ServicesType = new Type[] { typeof(IAService) }
        )]
        public class MyService : IAService, IBService
    ==等同于
    services.AddTransient<IAService, MyService>();
    3: [InjectOn(Own = true)]
       public class MyService : IMyService
    ==等同于
    services.AddTransient<IAService, MyService>();
    services.AddTransient<MyService>();
    4 如果服务继承了类、接口，只想注册父类，那么可以这样写：
        [InjectOn(
        Scheme = InjectScheme.OnlyBaseClass
        )]
    public class MyService : ParentService, IDisposable
    5 如果只注册自身，忽略接口等，可以使用：
    [InjectOn(ServiceLifetime.Scoped, Scheme = InjectScheme.None, Own = true)]
     */
    public class UserServices
    {
        private readonly IBaseRepository<SysUser> _baseRepository;
        private readonly IBaseRepository<SysMenu> _baseMenuRepository;
        private readonly IBaseRepository<SysRole> _baseRoleRepository;
        private readonly IBaseRepository<SysUserRole> _baseUserRoleRepository;
        private readonly IBaseRepository<SysRoleMenu> _baseRoleMenuRepository;
        private readonly UnitOfWork _unitOfWork; 

        public UserServices(IBaseRepository<SysUser> baseRepository,
            IBaseRepository<SysRole> baseRoleRepository, IBaseRepository<SysUserRole> baseUserRoleRepository,
            UnitOfWork unitOfWork, IBaseRepository<SysMenu> baseMenuRepository,
            IBaseRepository<SysRoleMenu> baseRoleMenuRepository)
        {
            _baseRepository = baseRepository;
            _baseRoleRepository = baseRoleRepository;
            _baseUserRoleRepository = baseUserRoleRepository;
            _unitOfWork = unitOfWork;
            _baseMenuRepository = baseMenuRepository;
            _baseRoleMenuRepository = baseRoleMenuRepository;
        }

        /// <summary>
        /// 获取用户信息
        /// </summary>
        /// <param name="loginName"></param>
        /// <param name="loginPwd"></param>
        /// <returns></returns>
        public async Task<SysUser> SaveUserInfo(string loginName, string loginPwd, CancellationToken ctk)
        {
            var user = await _baseRepository.SelectWhereAsync(x => x.Username.Equals(loginName.Trim(), StringComparison.CurrentCultureIgnoreCase));
            return user;

            //var tranction = await _unitOfWork.BeginTranAsync(ctk);
            //var s = await _baseRepository.SelectById(3);
            //s.name = "角色管理-修改";
            //await _baseRepository.UpdateAsync(s);
            ////await tranction.RollbackAsync(ctk);
            //await _unitOfWork.CommitTranAsync(ctk);

            //var tranction = await _unitOfWork.BeginTranAsync(ctk);
            //// 执行sql
            //var newName = "角色管理-修改";
            //await _baseRepository.ExecSql(@$"UPDATE sys_menu SET Name = {newName} where Id = 3 ");


            ////批量更新
            //await _baseRepository.UpdateBatchOkAsync(x => x.Id == 3 || x.Id == 2, x => x.SetProperty(b => b.Name, b => b.Name + "11"));
            //await tranction.RollbackAsync(ctk);



            //SysUserInfo sysUserInfo = new SysUserInfo(loginName, loginPwd);
            //SysUserInfo model = new SysUserInfo();
            //var userList = await base.Query(a => a.LoginName == sysUserInfo.LoginName && a.LoginPWD == sysUserInfo.LoginPWD);
            //if (userList.Count > 0)
            //{
            //    model = userList.FirstOrDefault();
            //}
            //else
            //{
            //    var id = await base.Add(sysUserInfo);
            //    model = await base.QueryById(id);
            //}

            //return model;

        }

        /// <summary>
        /// 根据用户ID获取用户信息
        /// </summary>
        /// <param name="username"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<SysUser> GetUserByUserIdAsync(long id)
        {
            return await _baseRepository.SelectWhereAsync(x => x.Id == id);
        }

        /// <summary>
        /// 根据用户名判断用户是否存在
        /// </summary>
        /// <param name="username"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<SysUser> GetUserByUserNameAsync(string username)
        {
             return await _baseRepository.SelectWhereAsync(x => x.Username.Equals(username));
        }
        /// <summary>
        /// 根据用户ID获取角色
        /// </summary>
        /// <param name="userId"></param>
        /// <returns></returns>
        public async Task<(List<string>, List<long>)> GetUserRolesByUserId(long userId)
        {
            var roleids = await _baseUserRoleRepository.SelectListWhereAsync(x => x.UserId == userId);
            var roles = await _baseRoleRepository.SelectListWhereAsync(x => roleids.Select(s => s.RoleId).Contains(x.Id));
            return (roles.Select(x => x.Code).ToList(), roleids.Select(x => x.RoleId).ToList());
        }
        /// <summary>
        /// 根据role获取菜单
        /// </summary>
        /// <param name="roleIds"></param>
        /// <returns></returns>
        public async Task<List<SysMenu>> GetUserMenusByRoleIds(List<long> roleIds)
        {
            var menuIds = (await _baseRoleMenuRepository.SelectListWhereAsync(x => roleIds.Contains(x.RoleId))).Select(x => x.MenuId);
            IEnumerable<long> needMenuIds = [1, 2, 3, 4, 5, 6, 20, 21];
            return await _baseMenuRepository.SelectListWhereAsync(x => menuIds.Contains(x.Id) && needMenuIds.Any(w=>w == x.Id));
        }

        /// <summary>
        /// 获取所有用户
        /// </summary>
        /// <returns></returns>
        public async Task<List<SysUser>> GetUserListAsync() 
        {
            var users = await _baseRepository.SelectAllAsync();
            return users;
        }

        /// <summary>
        /// 获取所有用户
        /// </summary>
        /// <returns></returns>
        public async Task<List<SysRole>> GetRoleListAsync()
        {
            return await _baseRoleRepository.SelectAllAsync();
        }
    }
}
